package com.crm.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.crm.commons.constant.Constant;
import com.crm.commons.domain.ResponseData;
import com.crm.commons.exception.BusinessException;
import com.crm.commons.exception.enumVo.BussinessExceptionEnum;
import com.crm.entity.CrmRole;
import com.crm.entity.CrmRoleUser;
import com.crm.service.ICrmRoleService;
import com.crm.service.ICrmRoleUserService;
import com.crm.util.StringUtil;
import com.crm.util.UUIDUtils;
import com.crm.vo.PageBean;
import com.crm.vo.SysUser;
import org.springframework.beans.factory.annotation.Value;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crm.commons.DataEnum;
import com.crm.commons.UserDto;
import com.crm.entity.CrmUser;
import com.crm.mapper.CrmUserMapper;
import com.crm.service.ICrmUserService;
import org.apache.commons.io.FileUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.crm.util.DateUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author junxian, dou
 * @since 2024-11-25
 */
@Service
public class CrmUserServiceImpl extends ServiceImpl<CrmUserMapper, CrmUser> implements ICrmUserService {


    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private ICrmRoleService roleService;

    @Resource
    private ICrmRoleUserService roleUserService;

    @Override
    public void saveUserDetails(UserDto user,CrmUser userInfo) {
        String userId = user.getId();
        if (StringUtil.isEmpty(userId)) {
            CrmUser entity = new CrmUser();
            entity.setId(UUIDUtils.getUUID());
            entity.setName(user.getUserName());
            entity.setLoginPwd(passwordEncoder.encode(Constant.DEFAULT_PASSWORD));
            entity.setAvatar(Constant.DEFAULT_AVATAR);
            entity.setDeptno(user.getDeptno());
            entity.setEmail(user.getEmail());
            entity.setExpireTime(DateTime.now().offset(DateField.MONTH, 3).toString());
            this.save(entity);
        } else {
            CrmUser crmUser = getCrmUser(userId);
            crmUser.setEmail(user.getEmail());
            crmUser.setLockState(user.getLockState());
            updateById(crmUser);
        }

    }

    @Override
    public Map<String, Object> uploadImage(MultipartFile file) {
        if (file.isEmpty()) {
            throw new BusinessException(BussinessExceptionEnum.FILE_IS_NOT_NULL);
        }
        Map<String, Object> dataMap = new HashMap<>();
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName = DateUtils.getCurrentDateStr() + suffixName;
        try {
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(avatarImagesFilePath + newFileName));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        dataMap.put("title", newFileName);
        return dataMap;
    }

    @Override
    public void updateAvatar(CrmUser userInfo) {
        CrmUser user = getCrmUser(userInfo.getId());
//        user.setEditTime(DateUtils.formateDateTime(new Date()));
        user.setAvatar(userInfo.getAvatar());
        updateById(user);
    }

    @Override
    public void updateEmail(CrmUser userInfo) {
        CrmUser user = getCrmUser(userInfo.getId());
        user.setEmail(userInfo.getEmail());
        updateById(user);
    }

    @Override
    public ResponseData updatePassWord(SysUser sysUser) {
        CrmUser user = getCrmUser(sysUser.getId());
        if (passwordEncoder.matches(sysUser.getOldPassword(), user.getLoginPwd())) {
            user.setLoginPwd(passwordEncoder.encode(sysUser.getNewPassword()));
            user.setExpireTime(DateTime.now().offset(DateField.MONTH, 3).toString());
            updateById(user);
            return ResponseData.success();
        } else {
            return ResponseData.error("输入旧密码错误！");
        }
    }

    @Override
    public PageBean selectUserList(PageBean pageBean) {
        Map<String,String> map = pageBean.getQuery();
        String query = map.get("name").trim();
        Page<CrmUser> objectPage = new Page<>(pageBean.getPageNum(), pageBean.getPageSize());

        QueryWrapper<CrmUser> queryWrapper = new QueryWrapper<CrmUser>().like(StringUtil.isNotEmpty(query), "name", query);
        Page<CrmUser> pageResult = this.page(objectPage, queryWrapper);
        List<CrmUser> userList = pageResult.getRecords();
        for (CrmUser user : userList) {
            List<CrmRole> roleList = roleService.list(new QueryWrapper<CrmRole>()
                    .inSql("id", "SELECT rid FROM crm_role_user WHERE uid = '" + user.getId()+"'"));
            user.setRoleList(roleList);
        }
        PageBean<CrmUser> pageVo = new PageBean();
        pageVo.setTList(userList);
        pageVo.setTotal(pageResult.getTotal());
        return pageVo;
    }

    @Override
    public UserDto getInfoById(String id) {
        CrmUser byId = getCrmUser(id);
        UserDto userDto = new UserDto();
        userDto.setId(byId.getId());
        userDto.setUserName(byId.getName());
        userDto.setLockState(byId.getLockState());
        userDto.setEmail(byId.getEmail());
        userDto.setDeptno(byId.getDeptno());
        return userDto;
    }

    private CrmUser getCrmUser(String id) {
        CrmUser byId = getById(id);
        if (ObjectUtil.isNull(byId)) {
            throw new BusinessException(BussinessExceptionEnum.USER_NOT_EXISTS);
        }
        return byId;
    }

    @Override
    public long getByUsername(String userName) {
        LambdaQueryWrapper<CrmUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CrmUser::getName,userName);
        return this.count(wrapper);
    }

    @Override
    public void deleteByUserId(String[] ids) {
        removeByIds(Arrays.asList(ids));
        LambdaQueryWrapper<CrmRoleUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CrmRoleUser::getUid,ids);
        roleUserService.remove(wrapper);
    }

    @Override
    public void resetPassWord(String id) {
        CrmUser byId = getCrmUser(id);
        byId.setLoginPwd(passwordEncoder.encode(Constant.DEFAULT_PASSWORD));
        byId.setExpireTime(DateTime.now().offset(DateField.MONTH, 3).toString());
        updateById(byId);
    }

    @Override
    public void updateStatus(String id, String status) {
        CrmUser byId = getCrmUser(id);
        byId.setLockState(status);
        updateById(byId);
    }

    @Transactional
    @Override
    public void grantRole(String userId, Long[] roleIds) {
        List<CrmRoleUser> userRoleList = new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            CrmRoleUser sysUserRole = new CrmRoleUser();
            sysUserRole.setRid(r);
            sysUserRole.setUid(userId);
            userRoleList.add(sysUserRole);
        });
        LambdaQueryWrapper<CrmRoleUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CrmRoleUser::getUid,userId);
        roleUserService.remove(wrapper);
        roleUserService.saveBatch(userRoleList);
    }

    @Override
    public List<CrmUser> getOwnerList() {
        LambdaQueryWrapper<CrmUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(CrmUser::getId,CrmUser::getName);
        return list(wrapper);
    }
}
